/*
 * compresor de videos raw a videos FFV1
 * Copyright (C) 2008  Jesus Nuevo - UAH

 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "frame_header.hh"


static void headerv1tov2(struct frame_headerv1* v1, struct frame_headerv2 *v2)
{

    memcpy(v2, v1, sizeof(struct frame_headerv1));
    
    v2->version = 2;
    v2->filltime.tv_sec = 0;
    v2->filltime.tv_usec = v1->counter;
    
}

int read_frame_header_version(FILE *f)
{

    off_t curr;
    curr = ftello(f);

    unsigned int start_code;
    unsigned int version;

    fread(&start_code, sizeof(uint), 1, f);
    if(start_code != FRAME_START_CODE){
	fseeko(f, curr, SEEK_SET);
	fprintf(stderr, "Bad header: bad START_CODE\n");
	return -1;
    }

    fread(&version, sizeof(uint), 1, f);
    
    fseeko(f,curr, SEEK_SET);

    return version;
}

int read_frame_header(FILE *f, struct frame_headerv2 *head)
{

    struct frame_headerv1 v1;
    off_t curr;
    curr = ftello(f);

    v1.start_code = 0;    

    fread(&v1, sizeof(struct frame_headerv1), 1, f); 
    fseeko(f, curr, SEEK_SET);

     if(v1.start_code != FRAME_START_CODE){
	fprintf(stderr, "Bad header: bad START_CODE\n");
	return -1;
    }

     if(v1.version == 2){
	 fread(head, sizeof(struct frame_headerv2), 1, f); 
	 fseeko(f, curr, SEEK_SET);
     }
     else{
	 headerv1tov2(&v1, head);
     }

     return 0;
}


int read_frame_header(FILE *f, struct frame_headerv1 *head)
{

    off_t curr;

    curr = ftello(f);

    head->start_code = 0;

    fread(head, sizeof(struct frame_headerv1), 1, f); 

    fseeko(f, curr, SEEK_SET);
    
    if(head->start_code != FRAME_START_CODE){
	fprintf(stderr, "Bad header: bad START_CODE\n");
	return -1;
    }

    if(head->version == 1){
 	head->version = 1;
   }    


    return 0;   
}

int check_frame_header(const IplImage *img, unsigned int frame, 
		       struct frame_headerv1 *hout)
{

    //check the first bytes are the FRAME_START_CODE
    
    int code = *((int*)img->imageData);
    if(code != FRAME_START_CODE)
	return -1;

    //and that size and frame are correct
    struct frame_headerv1 h;

    memcpy(&h, img->imageData, sizeof(struct frame_headerv1)); 
    if(hout)
    memcpy(hout, img->imageData, sizeof(struct frame_headerv1)); 


//     sscanf(img->imageData, "%4c %d %d %d %d %d %d", h.start_code, &(h.version), &h.nframe,
// 	   &(h.counter), &(h.width), &(h.height), &(h.ncameras));

    if(frame != h.nframe)
	return 1;
    
    if((unsigned int)img->width != h.width || (unsigned int)img->height!=(h.height*h.ncameras))
	return -2;
    
    return 0;
}


// int write_frame_header(const IplImage *img, int nframe, int ncameras, int fps)
// {

//     int sz = sizeof(struct frame_headerv1);
//     if(img->imageSize <= sz)
// 	return 0;
//     if(img->widthStep <= sz){
// 	fprintf(stderr, "Header is bigger than 1line");
//     }

//     struct frame_headerv1 head;

//     head.start_code = FRAME_START_CODE;
//     head.version = 1;
//     head.nframe = nframe;
//     head.counter = 0;
//     head.width = img->width;    
//     head.height = img->height;
//     head.ncameras = ncameras;
//     strncpy(head.color_space, img->colorModel, 4);
//     head.fps = fps;
//     head.shutter = 0;
//     head.gain = 0;
//     head.brightness = 0;
//     head.lighting = 0;

//     memcpy(img->imageData, &head, sz);

//     return 0;

// }


frame_header * read_image(IplImage * img, FILE * f, CvSize video_size)
{
    CvSize s = cvGetSize(img);
    char * datainit = img->imageData + (s.height-video_size.height)/2*s.width;
    fread((void*) datainit, video_size.width*video_size.height, 1, f);
    return  (frame_header*) datainit;
}
